# !/usr/bin/env python
# encoding: utf-8


"""
  @author: gaogao
  @file: mueller_matrix .py
  @time: 2022/3/18 11:34
  @desc:穆勒矩阵的脚本1
"""
import time

from math import *
from ATS.hardwarescan import conf_file_manager
from ATS.application.LCR_App.U2722A_App import U2722A_App
from ATS.application.LASER_App.L8164B_App import L8164B_App
from ATS.application.LASER_App.N7786C_App import N7786C_App
from ATS.util.calcu_step_util import get_step_list


# wave_length=13101
def oe_te_alignment(para):
    # l8164b_app.cls()

    # if len(para.smu_setting) == 1:
    #     for smu_setting in para.smu_setting:
    #         u2722a_app = U2722A_App(smu_setting.smu)
    #         channel = smu_setting.channel
    #         voltage = smu_setting.voltage_list[0]
    #         voltage_range = smu_setting.voltage_range
    #         nplc = smu_setting.nplc
    #         current_range = smu_setting.current_range
    #         current_limit = smu_setting.current_limit

    smu_setting = para.smu_setting
    smu_dict = {}
    # smu voltage_list channel nplc current_range current_limit //mode sweep
    #
    mes_plans_dict = {"var_func": None, "var1": None, "measure_func": None}
    init_set_list = []
    sweep_channel_open = {"sweep": None}
    if smu_setting:
        for smu in smu_setting:
            if smu["smu"] not in smu_dict:
                smu_dict[smu["smu"]] = U2722A_App(smu["smu"])
            current_inst = smu_dict[smu["smu"]]
            current_voltage_list = smu["voltage_list"]
            current_channel = smu["channel"]
            current_channel_nplc = smu["nplc"]
            current_channel_range = smu["current_range"]
            current_channel_limit = smu["current_limit"]
            init_set_list += [lambda y=current_channel,
                                     inst_obj=current_inst: inst_obj.output_state(0, y),

                              lambda x=current_channel, inst_obj=current_inst: inst_obj.set_voltage_range(x),
                              lambda x=current_channel_nplc, y=current_channel,
                                     inst_obj=current_inst: inst_obj.set_current_nplc(x, y),
                              lambda x=current_channel_range, y=current_channel_limit,
                                     z=current_channel, inst_obj=current_inst: inst_obj.set_current_range_limit(x, y,
                                                                                                                z)]
            if smu["mode"] == "sweep":
                mes_plans_dict["var1"] = current_voltage_list
                mes_plans_dict["var_func"] = lambda volt, x=current_channel, inst_obj=current_inst: \
                    inst_obj.set_voltage(volt, x)
                sweep_channel_open["sweep"] = lambda y=current_channel, inst_obj=current_inst: inst_obj.output_state(1,
                                                                                                                     y)
            else:
                init_set_list += [lambda volt=current_voltage_list[0], x=current_channel, inst_obj=current_inst: \
                                      inst_obj.set_voltage(volt, x)]

            if smu["is_measure"]:
                mes_plans_dict["measure_func"] = lambda x=current_channel, inst_obj=current_inst: abs(
                    float(inst_obj.get_current_value(x)))
            init_set_list += [lambda y=current_channel, inst_obj=current_inst: inst_obj.output_state(1, y)]

        # set init
        for inst_set_func in init_set_list:
            inst_set_func()  # 设置SMU

        # read mes
        # current_list = []  # result list
        # mes_func = mes_plans_dict["measure_func"]
        # if mes_func:  # mes func不为空
        #     if mes_plans_dict["var1"]:  # sweep
        #         for volt in mes_plans_dict["var1"]:
        #             mes_plans_dict["var_func"](volt)
        #             current_list.append(mes_func())
        #     else:
        #         current_list.append(mes_func())  # spot

    l8164b_app = L8164B_App(para.l8164_setting.title)

    n7786c_app = N7786C_App("SS1")

    l8164b_app.set_power_unit()
    l8164b_app.set_power_value(para.l8164_setting.power_value)
    l8164b_app.set_wave_length(para.l8164_setting.wave_length)
    time.sleep(int(para.l8164_setting["stable_time"]))
    l8164b_app.output_on()

    # u2722a_app.set_voltage_range(channel)
    # u2722a_app.set_current_range_limit(current_range, current_limit, channel)
    # u2722a_app.set_current_nplc(nplc, channel)
    # u2722a_app.set_voltage(voltage, channel)
    # u2722a_app.output_state(1, channel)

    n7786c_app.set_stabilization_mode(1)
    # 7786的稳定时间
    stable_schedule = 0.5
    current_list = []
    # 固定的偏振值
    polarization_list = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, 0, 1]]
    for polarization in polarization_list:
        n7786c_app.set_polarization_value(*polarization)
        time.sleep(stable_schedule)
        current = float(mes_plans_dict["measure_func"]())
        # current = float(u2722a_app.get_current_value(channel))
        current_list.append(current)
    u2722a_app.output_state(0, channel)
    if current_list:
        calculate_set_stability(current_list)
    # return current_list


def calculate_set_stability(data_list):
    m11 = (data_list[0] + data_list[1]) / 2
    m12 = (data_list[0] - data_list[1]) / 2
    m13 = data_list[2] - m11
    m14 = data_list[3] - m11
    x1 = m12 / sqrt(pow(m12, 2) + pow(m13, 2) + pow(m14, 2))
    x2 = m13 / sqrt(pow(m12, 2) + pow(m13, 2) + pow(m14, 2))
    x3 = m14 / sqrt(pow(m12, 2) + pow(m13, 2) + pow(m14, 2))
    n7786c_app.set_polarization_value(x1, x2, x3)


oe_te_alignment(locals()["para"])
